package com.mbc.common.manager;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.NoResultException;

import com.mbc.common.data.BranchDataList;
import com.mbc.common.data.ReferenceData;
import com.mbc.common.entities.Branch;
import com.mbc.common.exception.DataDuplicationException;
import com.mbc.common.exception.ForeignConflictException;
import com.mbc.common.param.CriteriaParams;
import com.mbc.common.utils.KeyGenerator;


public class BranchMgr extends AbstractMgr {
	
	public BranchMgr(){}
	
	public BranchMgr(String sessionId){
		this.sessionId = sessionId;
	}
	
	public void createBranch(Branch branch)throws Exception{
		openConnection();
		try {
			beginTransaction();
			branch.setBranchId(KeyGenerator.generateKey(entityManager));
			entityManager.persist(branch);
			commitTransaction();
		} catch (Exception e) {
			rollbackTransaction();
			if(DataDuplicationException.isUniqueKyeError(e))
				throw new DataDuplicationException(e.getMessage());
			else
				throw e;
		} finally {
			closeConnection();
		}
	}
	
	public void updateBranch(Branch branch)throws Exception{
		openConnection();
		try {
			beginTransaction();
			entityManager.merge(branch);
			commitTransaction();
		} catch (Exception e) {
			rollbackTransaction();
			throw e;
		} finally {
			closeConnection();
		}
	}
	
	public void deleteBranch(long key) throws Exception{
		openConnection();
		try {
			beginTransaction();
			Branch l_branch = entityManager.find(Branch.class, key);
			entityManager.remove(l_branch);
			commitTransaction();
		} catch (Exception e) {
			rollbackTransaction();
			if(e.getCause().getCause().getCause() instanceof SQLException){
				if(ForeignConflictException.FOREIGN_CONFLICT_ERROR_CODE == ((SQLException)e.getCause().getCause().getCause()).getErrorCode())
					throw new ForeignConflictException(e);
				else
					throw e;
			}
			else
				throw e;
		} finally {
			closeConnection();
		}
	}
	
	public Branch findBranch(long key) throws Exception{
		openConnection();
		try {
			return entityManager.find(Branch.class, key);
		} catch (Exception e) {
			throw e;
		} finally {
			closeConnection();
		}
	}
	
	public BranchDataList findBranch(CriteriaParams cri)throws Exception{
		openConnection();
		try {
            String l_cri = " where b.name like '%" + cri.getKeyword() + "%' or b.branchCode like '%" + cri.getKeyword() + "%'";
            String l_searchJPQL = "select b from Branch b" + l_cri;
            
            List<Branch> l_branchList = entityManager.createQuery(l_searchJPQL, Branch.class)
                    .setFirstResult(cri.getIndex())
                    .setMaxResults(cri.getSize())
                    .getResultList();
            
            BranchDataList l_dataList = new BranchDataList();
            l_dataList.setEntityList(l_branchList);
            
            if(cri.getIndex() == 0){
            	String l_countQuery = "select count(b.branchId) from Branch b" + l_cri;
            	l_dataList.setTotalRecord(entityManager.createQuery(l_countQuery, Long.class).getSingleResult());
            }
            
			return l_dataList;
		} catch (Exception e) {
			throw e;
		} finally{
			closeConnection();
		}
	}
	
	public List<Branch> getAllBranch()throws Exception{
		openConnection();
		try {
			return entityManager.createNamedQuery("Branch.findAll", Branch.class).getResultList();
		} catch (Exception e) {
			throw e;
		} finally{
			closeConnection();
		}
	}
	
	public ArrayList<ReferenceData<Long>> getBranchRefList()throws Exception{
		openConnection();
		try {
			List<Branch> l_branches = entityManager.createNamedQuery("Branch.findAll", Branch.class).getResultList();
			ArrayList<ReferenceData<Long>> l_references = new ArrayList<ReferenceData<Long>>();
			for (Branch branch : l_branches) {
				ReferenceData<Long> l_ref = new ReferenceData<Long>();
				l_ref.setKey(branch.getBranchId());
				l_ref.setValue(branch.getName());
				l_references.add(l_ref);
			}
			return l_references;
		} catch (Exception e) {
			throw e;
		} finally {
			closeConnection();
		}
	}
	
	public Branch findBranchByCode(String code) throws Exception {
		openConnection();
		try {
			try {
				return entityManager.createNamedQuery("Branch.findByBranchCode", Branch.class)
						.setParameter("branchCode", code)
						.getSingleResult();
			} catch (NoResultException innerEx) {
				return null;
			}
		} catch (Exception e) {
			throw e;
		} finally {
			closeConnection();
		}
	}
	
//	//Report
//	public JasperPrint prepareBranchReport(BranchRpt info) throws Exception {
//		openConnection();
//		JasperPrint l_jsPrint = null;
//		try {
//			//branchDAO = CommonDAOFactory.getBranchDAO(getConnection());
//
//			JRResultSetDataSource l_jrRS = new JRResultSetDataSource(branchDAO.prepareBranchReport(info));
//
//			JasperReport l_jsRpt = (JasperReport) JRLoader
//					.loadObjectFromFile(CommonSingleton.ABSOLUTE_PATH
//							+ "reports/BranchRpt.jasper");
//			HashMap<String, Object> l_params = new HashMap<String, Object>();
//			l_params.put("company", "MBC");
//			l_jsPrint = JasperFillManager.fillReport(l_jsRpt, l_params, l_jrRS);
//
//		} catch (JRException je) {
//			throw je;
//		} catch (Exception e) {
//			throw e;
//		} finally {
//			closeConnection();
//		}
//
//		return l_jsPrint;
//
//	}
}
